'use strict';

const Service = require('egg').Service;

const uuid = async conn => {
  const result = await conn.query("select REPLACE(UUID(),'-','') as uuid");
  return result[0].uuid;
};
class MenuService extends Service {
  constructor(ctx) {
    super(ctx);
    this.name = 'menu';
  }

  // * menu -1-mp-1- permission -n---n- role
  async create(params) {
    const { mysql } = this.app;
    const conn = await mysql.beginTransaction();
    const {
      parentId = null,
      name,
      icon,
      url,
      sort,
      description,
      type,
    } = params;
    const createBy = this.ctx.user.id;
    const createTime = new Date();
    try {
      const menu_id = await uuid(conn);
      await conn.query(
        'INSERT INTO sys_menu(id,  parent_id,  name,  icon,  url, sort,  description,  type, create_by, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);',
        [
          menu_id,
          parentId,
          name,
          icon,
          url,
          sort,
          description,
          type,
          createBy,
          createTime,
        ]
      );
      const permission_id = await uuid(conn);
      await conn.insert('sys_permission', {
        id: permission_id,
        created_at: createTime,
      });
      await conn.insert('sys_permission_menu', {
        permission_id,
        menu_id,
      });
      await conn.commit();
      return {
        id: menu_id,
      };
    } catch (error) {
      this.ctx.throw(500, error.message);
      await conn.rollback();
    }
  }

  async find(params) {
    const { mysql } = this.app;
    // const { Sys: { Menu } } = model;
    const { helper: { pagination } } = this.ctx;
    try {
      const { parentId, name, icon, sort, description, type, page, size } = params;
      const pagger = pagination(page, size);
      // const items = await Menu.findAll({
      //   ...pagger,
      // });
      // console.log('menu items', items);
      const filters = {
        parentId: {
          '=': parentId,
        },
        name: {
          '=': name,
        },
        icon: {
          '=': icon,
        },
        sort: {
          '=': sort,
        },
        description: {
          '=': description,
        },
        type: {
          '=': type,
        },
      };
      const segments = [];
      const values = [];
      const user_id = this.ctx.user.id;
      Object.keys(filters).forEach(key => {
        const item = filters[key];
        const k = Object.keys(item)[0];
        if (item[k]) {
          segments.push(`(${key} ${k} ? )`);
          values.push(item[k]);
        }
      });
      // const select = 'SELECT `sys_menu`.`id`,`sys_menu`.parent_id,`sys_menu`.`name`,`sys_menu`.`icon`,`sys_menu`.`url`,`sys_menu`.`type`,`sys_menu`.`sort`,`sys_menu`.`description`,`sys_menu`.`create_by`,`sys_menu`.`created_at`,`sys_permission_menu`.permission_id,`sys_permission`.action FROM `sys_permission`,`sys_menu`,`sys_permission_menu` WHERE `sys_permission`.id=`sys_permission_menu`.permission_id AND `sys_menu`.id=`sys_permission_menu`.menu_id AND `sys_permission`.id';
      const select = 'SELECT `sys_menu`.`id`,`sys_menu`.parent_id,`sys_menu`.`name`,`sys_menu`.`icon`,`sys_menu`.`url`,`sys_menu`.`type`,`sys_menu`.`sort`,`sys_menu`.`description`,`sys_menu`.`create_by`,`sys_menu`.`created_at`,`sys_permission_menu`.permission_id,`sys_permission`.action FROM `sys_permission`,`sys_menu`,`sys_permission_menu` WHERE `sys_permission`.id=`sys_permission_menu`.permission_id AND `sys_menu`.id=`sys_permission_menu`.menu_id AND `sys_permission`.id IN (SELECT `sys_role_permission`.permission_id FROM `sys_role`,`sys_permission`,`sys_role_permission` WHERE `sys_role`.id=`sys_role_permission`.role_id AND `sys_permission`.id=`sys_role_permission`.permission_id AND `sys_role`.id IN (SELECT `sys_role`.id FROM `sys_user`,`sys_role`,`sys_user_role` WHERE `sys_user`.id=`sys_user_role`.user_id AND `sys_role`.id=`sys_user_role`.role_id AND `sys_user`.id=?))';
      const wheres = segments.length ? `AND ${segments.join(' AND ')}` : '';
      const order = 'ORDER BY `created_at` ASC';
      const limit = 'LIMIT ? OFFSET ?';
      const count = await mysql.query(
        'SELECT COUNT(*) as `total` FROM (' + select + ') C ' + wheres,
        [ user_id, ...values ]
      );
      const result = await mysql.query(
        [ select, wheres, order, limit ].join(' '),
        [ user_id, ...values, pagger.limit, pagger.offset ]
      );
      return {
        pagination: {
          total: count[0].total,
          current: pagger.page,
          pageSize: pagger.size,
        },
        list: result,
      };
    } catch (error) {
      console.log(error);
      this.ctx.throw(500);
    }
  }

  async findOne(params) {
    const { mysql } = this.app;
    try {
      const { id } = params;
      const result = await mysql.get('sys_menu', { id });
      return result;
    } catch (error) {
      this.ctx.throw(500, error.message);
    }
  }

  async update(params) {
    const { mysql } = this.app;
    try {
      const { id, parentId, name, icon, url, sort, description, type } = params;
      const updateTime = new Date();
      const result = await mysql.query(
        'UPDATE `sys_menu` SET `parentId`=?, `name`=?, `icon`=?, `url`=?, `sort`=?, `description`=?, `type`=?, `updated_time`=? WHERE `id`=?',
        [ parentId, name, icon, url, sort, description, type, updateTime, id ]
      );
      if (result.affectedRows === 1) {
        return {};
      }
    } catch (error) {
      this.ctx.throw(500, error.message);
    }
  }

  async destroy(params) {
    const { mysql } = this.app;
    try {
      const { id } = params;
      const result = await mysql.delete('cms_category', { category_id: id });
      if (result.affectedRows === 1) {
        return {};
      }
    } catch (error) {
      this.ctx.throw(500, error.message);
    }
  }
}
module.exports = MenuService;
